﻿using Commons.Helpers;
using Commons.Responses;
using EntityModels.E09.Files;
using IApplicationServices;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;

namespace WebAPI.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class FileController : ControllerBase
    {
        private readonly IWebHostEnvironment _env;
        private readonly IFilePathService pathService;
        private readonly IFileHashService hashService;
        public FileController(IWebHostEnvironment env, IFilePathService pathService, IFileHashService hashService)
        {
            _env = env;
            this.pathService = pathService;
            this.hashService = hashService;
        }
        /// <summary>
        /// 检查文件是否存在,存在直接添加文件信息入库
        /// </summary>
        /// <param name="hash"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageResponse> CheckByHashAsync(string hash, string fileName)
        {
            return await FindByHashAsync(hash, fileName);
        }
        [HttpPost]
        [AllowAnonymous]
        public async Task<DataResponse<FilePath>> FileUploadAsync(IFormFile file)
        {
            try
            {
                var hash = CalculateHash(file);
                //检查文件是否存在，避免文件冗余
                var checkHash = await FindByHashAsync(hash, file.FileName);
                if (checkHash.Successed)
                {
                    return checkHash;
                }
                var dateName = DateTime.Now;
                string rootRoot = _env.ContentRootPath;
                var path = $"/UploadFiles/{dateName:yyyyMMdd}/";
                //后缀
                var fileSuffix = Path.GetExtension(file.FileName);
                //时间结尾的文件名
                var filePath = file.FileName.Substring(0, file.FileName.LastIndexOf('.')) + "_" + dateName.ToString("HHmmss") + fileSuffix;
                //完整的文件路径
                var completeFilePath = Path.Combine(path, filePath);
                var size = file.Length.ToString();

                //查看是否存在当天日期的文件夹
                if (!Directory.Exists(rootRoot + path))
                {
                    Directory.CreateDirectory(rootRoot + path);
                }

                using (var systeam = System.IO.File.Create(rootRoot + path + filePath))
                {
                    await file.CopyToAsync(systeam);
                    await systeam.FlushAsync();
                }
                var bo = new FilePath
                {
                    Size= size,
                    Name = filePath,
                    Path = completeFilePath
                };
                bo = await pathService.CreateAsync(bo);
                if (bo != null)
                {
                    var hbo = new FileHash(hash, completeFilePath,size);
                    var hres = await hashService.CreateAsync(hbo);
                    return new DataResponse<FilePath>(bo, "文件上传成功!");
                }
                throw new CustomException("文件上传失败!");
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 根据Id返回图片尺寸
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet]
        public async Task<string> GetDimensionsByIdAsync(Guid id)
        {
            var contentRootPath = _env.ContentRootPath;//>>>相当于HttpContext.Current.Server.MapPath("") 
            var file = await pathService.FindAsync(id);
            if (file == null) return null;
            var imgPath = contentRootPath + file.Path;
            return GetImageSizeAsync(imgPath);
        }

        /// <summary>
        /// 根据Id返回文件流
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet]
        public async Task<MemoryStream> GetFileByIdAsync(string? id)
        {
            var contentRootPath = _env.ContentRootPath;//>>>相当于HttpContext.Current.Server.MapPath("") 
            var file = await pathService.FindAsync(Guid.Parse(id));
            if (file == null)
            {
                file = await pathService.FindAsync(Guid.Parse("051822f6-be6e-4b56-91ae-73e030369c97"));
            }
            var imgPath = contentRootPath  + file.Path;
            try
            {
                var imgStream = new MemoryStream(System.IO.File.ReadAllBytes(imgPath));
                return imgStream;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return null;
            }
            //从图片中读取流
        }
        /// <summary>
        /// 通过路径获取图片尺寸
        /// </summary>
        /// <param name="imagePath"></param>
        /// <returns></returns>
        private string GetImageSizeAsync(string imagePath)
        {
            if (string.IsNullOrEmpty(imagePath) || !System.IO.File.Exists(imagePath))
            {
                return null; 
            }

            // 使用 Bitmap 类加载图片
            using (var image = SixLabors.ImageSharp.Image.Load(imagePath))
            {
                return image.Width.ToString() +","+ image.Height.ToString();
            }
        }

        /// <summary>
        /// 检查文件是否存在,存在直接添加文件信息入库
        /// </summary>
        /// <param name="hash"></param>
        /// <returns></returns>
        private async Task<DataResponse<FilePath>> FindByHashAsync(string hash, string fileName)
        {
            var hashFile = await hashService.FileByHashAsync(hash);
            if (hashFile != null)
            {
                var res = await pathService.CreateByPathAsync(fileName, hashFile.Path,hashFile.Size);
                if (res != null)
                {
                    return new DataResponse<FilePath>(res, "文件上传成功!");
                }
            }
            return new DataResponse<FilePath>(200, "", false);
        }


        /// <summary>
        /// 计算文件hash
        /// </summary>
        /// <param name="file"></param>
        /// <param name="hash"></param>
        /// <returns></returns>
        private string CalculateHash(IFormFile file)
        {
            using (var stream = file.OpenReadStream())
            {
                using (var sha256 = SHA256.Create())
                {
                    byte[] fileHash = sha256.ComputeHash(stream);
                    string computedHash = BitConverter.ToString(fileHash).Replace("-", "").ToLower();

                    // 比较传递的哈希值和计算得到的哈希值
                    return computedHash;
                }
            }
        }

    }
}
